home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / BEERSRC.ZIP / XMODEASM.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-12-27  |  24.3 KB  |  1,476 lines

  1. ;---------------------------------------------------------;
  2. ;                                                         ;
  3. ;                                                         ;
  4. ;   This module contains GRAPHICS PRIMITIVES for          ;
  5. ;   VGA undocumented 320x240 256 color mode.              ;
  6. ;                                                         ;
  7. ;       written by Dany Schoch for Alpha-Helix            ;
  8. ;   Parts of this code first appeard in Dr.Dobb's         ;
  9. ;   September 1991 issue (during my military service).    ;
  10. ;                                                         ;
  11.  
  12.  
  13.  
  14.  
  15.     IDEAL
  16.     P286N
  17.     JUMPS
  18.  
  19.     MODEL    compact, c
  20.  
  21. include "xmode.ash"
  22.  
  23.  
  24.     dataseg
  25.  
  26. ; CRT port parameters to switch to 320x240 256c mode.
  27.  
  28. CRTParm    dw    00b06h            ; Vertical total.
  29.     dw    03e07h            ; Overflow.
  30.     dw    04109h            ; Cell height (1 to double scan).
  31.     dw    0d610h            ; v sync start.
  32.     dw    08c11h            ; v sync end and protect cr0-cr7.
  33.     dw    0b712h            ; Vertical display.
  34.     dw    00014h            ; turn off dword mode.
  35.     dw    0bf15h            ; v blank start.
  36.     dw    00416h            ; v blank end.
  37.     dw    0e317h            ; turn on byte mode.
  38. CRT_PARM_LENGTH    =    (($-CRTParm)/2)
  39.  
  40.  
  41.     codeseg
  42.  
  43.  
  44. ; Uses int 10h function 0 to set a video mode.
  45. proc    screenmode    mode:word
  46.  
  47.     mov    ax, [mode]
  48.     int    10h
  49.  
  50.     ret
  51.  
  52. endp    screenmode
  53.  
  54.  
  55. proc    setxmode    uses si di
  56.  
  57.     mov    ax, 13h            ; Let the BIOS set standard
  58.     int    10h            ;   mode 320x200 linear.
  59.  
  60.     mov    dx, SC_INDEX
  61.     mov    ax, 0604h
  62.     out    dx, ax            ; disable chain4 mode.
  63.     mov    ax, 0100h
  64.     out    dx, ax            ; Synchronous reset while
  65.                     ;   switching clock.
  66.  
  67.     mov    dx, MISC_OUTPUT
  68.     mov    al, 0e3h
  69.     out    dx, al            ; Select 25MHz dot clock & 60Hz
  70.                     ;   scanning rate.
  71.  
  72.     mov    dx, SC_INDEX
  73.     mov    ax, 0300h
  74.     out    dx, ax            ; Undo reset (restart sequencer).
  75.  
  76.     mov    dx, CRTC_INDEX
  77.     mov    al, 11h
  78.     out    dx, al
  79.     inc    dx
  80.     in    al, dx
  81.     and    al,7fh
  82.     out    dx, al
  83.     dec    dx
  84.     cld
  85.     mov    si, offset CRTParm
  86.     mov    cx, CRT_PARM_LENGTH
  87. @@loop:
  88.     lodsw
  89.     out    dx, ax
  90.     loop    @@loop
  91.  
  92. ;    mov    ax, 1001h        ; set overscan color.
  93. ;    mov    bh, 0eh
  94. ;    int    10h
  95.  
  96.     mov    dx, SC_INDEX
  97.     mov    ax, 0f02h
  98.     out    dx, ax
  99.     mov    es, [base]
  100.     sub    di, di
  101.     sub    ax, ax
  102.     mov    cx, 8000h
  103.     rep    stosw
  104.  
  105.     ret
  106.  
  107. endp    setxmode
  108.  
  109.  
  110. ; VGApresent is taken from the book "PC&PS/2 Video Systems" published
  111. ; by Microsoft Press.
  112. ; VGApresent returns a non zero value if a VGA or MCGA was found.
  113. proc    VGApresent
  114.  
  115.     mov    ax, 1a00h
  116.     int    10h                     ; call video bios for info.
  117.  
  118.     cmp    al, 1ah
  119.     je    @@exit            ; Exit if VGA or MCGA detected.
  120.  
  121.     xor    ax, ax
  122.  
  123. @@exit:
  124.     ret
  125.  
  126. endp    VGApresent
  127.  
  128.  
  129. proc    plot,    x:word, y:word, c:word
  130.  
  131.     mov    ax, BYTESPERLINE
  132.     mul    [y]
  133.     mov    bx, [x]
  134.     shr    bx, 1
  135.     shr    bx, 1
  136.     add    bx, ax
  137.     mov    es, [base]
  138.  
  139.     mov    cl, [byte x]
  140.     and    cl, 011b
  141.     mov    ax, 0100h + MAP_MASK
  142.     shl    ah, cl
  143.     mov    dx, SC_INDEX
  144.     out    dx, ax
  145.     mov    dx, GC_INDEX
  146.     mov    ax, 0ff00h + BIT_MASK
  147.     out    dx, ax
  148.  
  149.     mov    al, [byte c]
  150.     mov    [es:bx], al
  151.  
  152.     ret
  153.  
  154. endp    plot
  155.  
  156.  
  157. proc    getpixel,    x:word, y:word
  158.  
  159.     mov    ax, BYTESPERLINE
  160.     mul    [y]
  161.     mov    bx, [x]
  162.     shr    bx, 1
  163.     shr    bx, 1
  164.     add    bx, ax
  165.     mov    es, [base]
  166.  
  167.     mov    ah, [byte x]
  168.     and    ah, 011b
  169.     mov    al, 04h
  170.     mov    dx, GC_INDEX
  171.     out    dx, ax
  172.  
  173.     mov    al, [es:bx]
  174.     sub    ah, ah
  175.  
  176.     ret
  177.  
  178. endp    getpixel
  179.  
  180.  
  181. proc    gostarfield    uses si di
  182.  
  183.     mov    [_sfield.go], TRUE
  184.  
  185.     mov    dx, GC_INDEX
  186.     mov    ax, 0ff00h + BIT_MASK
  187.     out    dx, ax
  188.  
  189.     mov    dx, SC_INDEX
  190.     mov    ax, 0100h + MAP_MASK
  191.     out    dx, ax
  192.  
  193.     mov    ax, BYTESPERLINE
  194.     mul    [windowy1]
  195.  
  196.     mov    es, [base]
  197.     mov    di, [page]              ; Flip page address so di is
  198.     xor    di, PAGESIZE            ;   pointing to the hidden screen.
  199.     mov    dl, [byte backgrndcolor]
  200. ; Clear stars on second page.
  201.     mov    cx, [_sfield.n]
  202.     lds    si, [_sfield.star]
  203.  
  204. @@next:
  205.     mov    bx, [(starstrc ptr si).x]
  206.     add    bx, [(starstrc ptr si).speed]
  207.     cmp    bx, ax
  208.     jb    @@skip
  209.     sub    bx, ax
  210. @@skip:
  211.     mov    [es:bx+di], dl        ; Clear pixel.
  212.     add    si, size starstrc
  213.     loop    @@next
  214.  
  215.     mov    ax, DGROUP
  216.     mov    ds, ax
  217.  
  218.     ret
  219.  
  220. endp    gostarfield
  221.  
  222.  
  223. proc    stopstarfield    uses si di
  224.  
  225.     mov    [_sfield.go], FALSE
  226.  
  227.     mov    dx, GC_INDEX
  228.     mov    ax, 0ff00h + BIT_MASK
  229.     out    dx, ax
  230.  
  231.     mov    dx, SC_INDEX
  232.     mov    ax, 0100h + MAP_MASK
  233.     out    dx, ax
  234.  
  235.     mov    es, [base]
  236.     mov    di, [page]              ; Flip page address so di is
  237.     xor    di, PAGESIZE            ;   pointing to the hidden screen.
  238.     mov    dl, [byte backgrndcolor]
  239. ; Clear stars on second page.
  240.     mov    cx, [_sfield.n]
  241.     lds    si, [_sfield.star]
  242. @@next:
  243.     mov    bx, [(starstrc ptr si).x]
  244.     mov    [byte es:bx+di], dl    ; Clear pixel.
  245.     add    si, size starstrc
  246.     loop    @@next
  247.  
  248.     mov    ax, DGROUP
  249.     mov    ds, ax
  250.  
  251.     ret
  252.  
  253. endp    stopstarfield
  254.  
  255.  
  256. proc    starfield uses si di
  257.  
  258.     cmp    [_sfield.active], FALSE
  259.     je    @@exit
  260.  
  261.     mov    dx, GC_INDEX
  262.     mov    ax, 0ff00h + BIT_MASK
  263.     out    dx, ax
  264.  
  265.     mov    dx, SC_INDEX
  266.     mov    ax, 0100h + MAP_MASK
  267.     out    dx, ax
  268.  
  269.     mov    es, [base]
  270.  
  271.     mov    ax, BYTESPERLINE
  272.     mul    [windowy1]
  273.  
  274.     mov    di, [page]
  275.     mov    cx, [_sfield.n]
  276.     mov    dl, [byte backgrndcolor]    ; Preload backgroundcolor.
  277.  
  278.     cmp    [_sfield.go], TRUE
  279.     jne    @@stay
  280.  
  281.     lds    si, [_sfield.star]
  282. @@next1:
  283.     mov    bx, [(starstrc ptr si).x]
  284.     mov    [byte es:bx+di], dl    ; Clear pixel.
  285.  
  286.     add    bx, [(starstrc ptr si).speed]
  287.     cmp    bx, ax                ; Check for wrap around.
  288.     jb    @@skip1
  289.     sub    bx, ax
  290. @@skip1:
  291.     mov    [(starstrc ptr si).x], bx
  292.     add    bx, [(starstrc ptr si).speed]
  293.     cmp    bx, ax
  294.     jb    @@skip2
  295.     sub    bx, ax
  296. @@skip2:
  297.     mov    dh, [byte (starstrc ptr si).color]
  298.     mov    [es:bx+di], dh        ; Set pixel.
  299.  
  300.     add    si, size starstrc
  301.     loop    @@next1
  302.     jmp    @@exit
  303.  
  304. @@stay:
  305.     lds    si, [_sfield.star]
  306.  
  307. @@next2:
  308.     mov    bx, [(starstrc ptr si).x]
  309.     add    bx, [(starstrc ptr si).speed]
  310.     cmp    bx, ax
  311.     jb    @@skip3
  312.     sub    bx, ax
  313. @@skip3:
  314.     mov    dh, [byte (starstrc ptr si).color]
  315.     mov    [es:bx+di], dh        ; Set pixel.
  316.     add    si, size starstrc
  317.     loop    @@next2
  318.  
  319. @@exit:
  320.     mov    ax, DGROUP
  321.     mov    ds, ax
  322.  
  323.     ret
  324.  
  325. endp    starfield
  326.  
  327.  
  328. ; defobject.
  329. ; This sub defines an animated object.
  330. ; args: A HANDLE of a sprite and the xstart and ystart coords.
  331. ; ret : HANDLE if free slot found or else ...  have a guess.
  332.  
  333. proc    defobject uses si,    sprite:word, x:word, y:word, flags:word
  334.  
  335.     mov    dx, 3
  336.  
  337. @@start:
  338.     dec    dx
  339.     mov    ax, -1
  340.     jz    @@ret
  341.  
  342.     mov    si, (offset _obj) + (MAXOBJS/2)*size objstrc
  343.     mov    cx, MAXOBJS/2
  344.     mov    ax, -size objstrc
  345.     test    [flags], OBJ_HIGH
  346.     jz    @@next
  347.     mov    ax, size objstrc
  348. @@next:
  349.     cmp    [(objstrc ptr si).active], FALSE
  350.     je    @@found
  351.     add    si, ax
  352.     dec    cx
  353.     jnz    @@next
  354.     xor    [flags], OBJ_HIGH        ; Invert priority bit.
  355.     jmp    @@start
  356.  
  357. @@found:
  358.  
  359.     mov    ax, [sprite]
  360.     mov    [(objstrc ptr si).sprite], ax
  361.     call    getspritesize,    ax
  362.     mov    [(objstrc ptr si).xs], ax
  363.     mov    [(objstrc ptr si).ys], dx
  364.     mov    [(objstrc ptr si).nadd], bx
  365.     mov    [(objstrc ptr si).maxn], cx
  366.     mov    [(objstrc ptr si).n], 0
  367.  
  368.     mov    ax, [x]
  369.     mov    [(objstrc ptr si).x], ax
  370.     mov    [(objstrc ptr si).xa], ax
  371.     mov    [(objstrc ptr si).xb], ax
  372.     mov    bx, [y]
  373.     mov    [(objstrc ptr si).y], bx
  374.     mov    [(objstrc ptr si).ya], bx
  375.     mov    [(objstrc ptr si).yb], bx
  376.     mov    ax, [flags]
  377.     and    ax, OBJ_ONECYCLE
  378.     mov    [(objstrc ptr si).cycle], ax
  379.     mov    [(objstrc ptr si).flags], 0
  380.  
  381.     mov    [(objstrc ptr si).destroy], 0
  382.     mov    [(objstrc ptr si).active], TRUE
  383.     mov    ax, si
  384.     sub    ax, offset _obj
  385.     mov    bl, size objstrc
  386.     div    bl
  387.  
  388. @@ret:
  389.     ret
  390.  
  391. endp    defobject
  392.  
  393.  
  394. ; moveobject.
  395. ; Moves the OBJECT 'obj' to the given location.
  396. ; RETURNS: ax = 0 if sprite cycled. ax != 0 otherwise.
  397.  
  398. proc    moveobject,    obj:word, x:word, y:word
  399.  
  400.     mov    bx, [obj]
  401.     imul    bx, size objstrc
  402.  
  403.     add    bx, offset _obj
  404.  
  405.     mov    ax, [x]
  406.     mov    [(objstrc ptr bx).x], ax
  407.     mov    ax, [y]
  408.     mov    [(objstrc ptr bx).y], ax
  409.  
  410.     ret
  411.  
  412. endp    moveobject
  413.  
  414.  
  415. ; moveobjectdelta.
  416. ; Moves the OBJECT 'obj' relative by the given values.
  417.  
  418. proc    moveobjectdelta,    obj:word, deltax:word, deltay:word
  419.  
  420.     mov    bx, [obj]
  421.     MASM
  422.     imul    bx, type objstrc
  423.     IDEAL
  424.  
  425.     add    bx, offset _obj
  426.  
  427.     mov    ax, [deltax]
  428.     add    [(objstrc ptr bx).x], ax
  429.     mov    ax, [deltay]
  430.     add    [(objstrc ptr bx).y], ax
  431.  
  432.  
  433.     ret
  434.  
  435. endp    moveobjectdelta
  436.  
  437.  
  438. ; Set the object's flash bit. This will paint it
  439. ; in the current flashcolor for one frame.
  440. proc    flash,    obj:word
  441.  
  442.     mov    bx, [obj]
  443.     imul    bx, size objstrc
  444.     add    bx, offset _obj
  445.  
  446.     or    [(objstrc ptr bx).flags], O_FLASH
  447.  
  448.     ret
  449.  
  450. endp    flash
  451.  
  452.  
  453. ; Change the object's look.
  454. proc    changesprite uses si,    obj:word, sprite:word
  455.  
  456.     mov    si, [obj]
  457.     imul    si, size objstrc
  458.     add    si, offset _obj
  459.  
  460.     mov    ax, [sprite]
  461.     mov    [(objstrc ptr si).sprite], ax
  462.     call    getspritesize, ax
  463.     mov    [(objstrc ptr si).maxn], cx
  464.     mov    [(objstrc ptr si).n], 0
  465.     mov    [(objstrc ptr si).xs], ax
  466.     mov    [(objstrc ptr si).ys], dx
  467.  
  468.     ret
  469.  
  470. endp    changesprite
  471.  
  472.  
  473. ; Kills object and removes it from both screen pages during next
  474. ; two calls to 'updatescreen'.
  475. proc    abandonobject,     obj:word
  476.  
  477.     mov    bx, [obj]
  478.     imul    bx, size objstrc
  479.     add    bx, offset _obj
  480.  
  481.     mov    [(objstrc ptr bx).destroy], 2
  482.  
  483.     ret
  484.  
  485. endp    abandonobject
  486.  
  487.  
  488. ; Kills object and imediately removes it from both screen pages.
  489. proc    killobject,    obj:word
  490.  
  491.     mov    bx, [obj]
  492.     imul    bx, size objstrc
  493.     add    bx, offset _obj
  494.  
  495.     call    removesprite, [(objstrc ptr bx).sprite],\
  496.                   [(objstrc ptr bx).x],\
  497.                   [(objstrc ptr bx).y]
  498.     xor    [page], PAGESIZE    ; Flip pages.
  499.     call    removesprite, [(objstrc ptr bx).sprite],\
  500.                   [(objstrc ptr bx).xa],\
  501.                   [(objstrc ptr bx).ya]
  502.     xor    [page], PAGESIZE
  503.     mov    [(objstrc ptr bx).active], FALSE
  504.  
  505.     ret
  506.  
  507. endp    killobject
  508.  
  509.  
  510. proc    killallobjects uses si di
  511.  
  512.     mov    si, MAXOBJS
  513.     mov    di, offset _obj
  514.  
  515. @@next:
  516.     mov    [(objstrc ptr di).active], FALSE
  517.  
  518.     add    di, size objstrc
  519.  
  520.     dec    si
  521.     jnz    @@next
  522.  
  523.     ret
  524.  
  525. endp    killallobjects
  526.  
  527.  
  528. ; crashtest.
  529. ; This procy tests whether the given objects 'obj1' and 'obj2'
  530. ; are overlapping each other. If so 1 will be returned, otherwise 0.
  531.  
  532. proc    crashtest uses si di,    obj1:word, obj2:word
  533.  
  534.     mov    si, [obj1]
  535.     imul    si, size objstrc
  536.     add    si, offset _obj
  537.     mov    di, [obj2]
  538.     imul    di, size objstrc
  539.     add    di, offset _obj
  540.  
  541. ; Check x coords.
  542.  
  543.     mov    ax, [(objstrc ptr si).x]
  544.     mov    bx, ax
  545.     add    bx, [(objstrc ptr si).xs]
  546.     sub    ax, [(objstrc ptr di).xs]
  547.     mov    dx, [(objstrc ptr di).x]
  548.     cmp    ax, dx
  549.     jg    @@skip2
  550.     cmp    bx, dx
  551.     jl    @@skip2
  552.  
  553. ; Check y coords.
  554.  
  555.     mov    ax, [(objstrc ptr si).y]
  556.     mov    bx, ax
  557.     add    bx, [(objstrc ptr si).ys]
  558.     sub    ax, [(objstrc ptr di).ys]
  559.     mov    dx, [(objstrc ptr di).y]
  560.     cmp    ax, dx
  561.     jg    @@skip2
  562.     cmp    bx, dx
  563.     jl    @@skip2
  564.  
  565.     mov    ax, 1            ; H I T  !!!!!
  566.     jmp    @@exit
  567.  
  568. @@skip2:
  569.     xor    ax, ax
  570.  
  571. @@exit:
  572.     ret
  573.  
  574. endp    crashtest
  575.  
  576.  
  577.  
  578. ; getobjectpos: returns current (x, y) coordinates and size (xs, ys)
  579. ;               of object obj.
  580. ;        (x, y) go into (ax, dx).
  581. ;        (xs, ys) will be returned in (bx, cx).
  582.  
  583. proc    getobjectpos,    obj:word
  584.  
  585.     mov    bx, [obj]
  586.     imul    bx, size objstrc
  587.     add    bx, offset _obj
  588.  
  589.     mov    ax, [(objstrc ptr bx).xa]    ; x pos.
  590.     mov    dx, [(objstrc ptr bx).ya]       ; y pos;
  591.     mov    cx, [(objstrc ptr bx).ys]       ; y size.
  592.     mov    bx, [(objstrc ptr bx).xs]    ; x size.
  593.  
  594.     ret
  595.  
  596. endp    getobjectpos
  597.  
  598.  
  599. proc    getobjectsize,    obj:word
  600.  
  601.     mov    bx, [obj]
  602.     imul    bx, size objstrc
  603.     add    bx, offset _obj
  604.  
  605.     mov    ax, [(objstrc ptr bx).xs]
  606.     mov    dx, [(objstrc ptr bx).ys]
  607.  
  608.     ret
  609.  
  610. endp    getobjectsize
  611.  
  612.  
  613. proc    getspritesize,    handle:word
  614.  
  615.     mov    bx, [handle]
  616.     imul    bx, size lowspr
  617.     add    bx, offset _sprite
  618.  
  619.     mov    ax, [(lowspr ptr bx).xs]
  620.     mov    dx, [(lowspr ptr bx).ys]
  621.     mov    cx, [(lowspr ptr bx).maxn]
  622.     mov    bx, [(lowspr ptr bx).nadd]
  623.  
  624.     ret
  625.  
  626. endp    getspritesize
  627.  
  628.  
  629. ; Checks whether the object is out of the currently defined
  630. ; action window.
  631. proc    outofwindow,    obj:word
  632.  
  633.     mov    bx, [obj]
  634.     imul    bx, size objstrc
  635.     add    bx, offset _obj
  636.  
  637.     mov    ax, [(objstrc ptr bx).x]
  638.     cmp    ax, [windowx0]
  639.     jl    @@out
  640.     cmp    ax, [windowx1]
  641.     jg    @@out
  642.  
  643.     mov    ax, [(objstrc ptr bx).y]
  644.     cmp    ax, [windowy0]
  645.     jl    @@out
  646.     cmp    ax, [windowy1]
  647.     jg    @@out
  648.  
  649.     xor    ax, ax
  650.     jmp    @@exit
  651.  
  652. @@out:
  653.     mov    ax, 1
  654.  
  655. @@exit:
  656.     ret
  657.  
  658. endp    outofwindow
  659.  
  660.  
  661. ; showpage: displays the page (0 or 1) on the screen.
  662.  
  663. proc    showpage,    p:word
  664.  
  665.     mov    ax, [p]
  666.     imul    ax, PAGESIZE
  667.  
  668.     call    showofs, ax
  669.  
  670.     ret
  671.  
  672. endp    showpage
  673.  
  674.  
  675. proc    showline,    line:word
  676.  
  677.     mov    ax, [line]
  678.     imul    ax, BYTESPERLINE
  679.  
  680.     call    showofs, ax
  681.  
  682.     ret
  683.  
  684. endp    showline
  685.  
  686.  
  687. proc    showofs,    ofs:word
  688.  
  689. ; Wait for display enable to be active, to be sure
  690. ;   both halfes of the start address will take in the same frame.
  691.  
  692.     mov    bl, START_ADDR_LOW
  693.     mov    bh, [byte ofs]
  694.     mov    cl, START_ADDR_HIGH
  695.     mov    ch, [byte ofs + 01h]
  696.  
  697.     mov    dx, INPUT_STATUS
  698.  
  699. @@wait1:
  700.     in    al, dx
  701.     test    al, 01h
  702.     jnz    @@wait1
  703.  
  704.     mov    dx, CRTC_INDEX
  705.     mov    ax, bx
  706.     out    dx, ax
  707.     mov    ax, cx
  708.     out    dx, ax
  709.  
  710. ; Now wait for vertical sync, so the other page will be invisible if
  711. ;   we start draw to it.
  712.  
  713.     mov    dx, INPUT_STATUS
  714.  
  715. @@wait2:
  716.     in    al, dx
  717.     test    al, 08h
  718.     jz    @@wait2
  719.  
  720.     ret
  721.  
  722. endp    showofs
  723.  
  724.  
  725. ; putspritedirect.
  726. ; Without the aid of defsprite directly draw a sprite.
  727. ; This routine doesn't perform any clipping.
  728. ; The sprite will be draw to BOTH screens.
  729.  
  730. proc    putspritedirect uses si di,    sprite:far ptr, x:word, y:word, n:word
  731.  
  732. local    xs:word, ofs:word
  733.  
  734.     mov    ax, 0ff00h + BIT_MASK
  735.     mov    dx, GC_INDEX
  736.     out    dx, ax
  737.  
  738.     mov    cl, [byte x]
  739.     and    cl, 011b        ; Calculate Map.
  740.     mov    bh, 00010001b
  741.     shl    bh, cl
  742.  
  743. ; Calculate screen memory location of first write. (es:di)
  744.     mov    ax, BYTESPERLINE
  745.     mul    [y]
  746.     mov    di, [x]
  747.     shr    di, 2
  748.     add    di, ax
  749.     mov    es, [base]
  750.  
  751.     lds    si, [sprite]
  752.     mov    ax, [(sprstrc ptr si).xs]
  753.     mov    [xs], ax
  754.     mov    dx, [(sprstrc ptr si).ys]
  755.     mov    bl, dl
  756.     mul    dx
  757.     xor    dx, dx
  758.     mul    [n]
  759.     lea    si, [(sprstrc ptr si).data]
  760.     add    si, ax
  761.     mov    dx, SC_INDEX
  762.  
  763. ; Now:
  764. ; bl : y loop counter
  765. ; cx : x loop counter
  766. ; al : alround
  767. ; ah : MAP_MASK value that will be updated every dot.
  768. ; bh : MAP_MASK of the first x coordinate.
  769. ; dx : Port addr.
  770.  
  771. @@yloop:
  772.     mov    cx, [xs]
  773.     mov    ah, bh
  774.     mov    [ofs], di
  775. @@xloop:
  776.     mov    al, MAP_MASK
  777.     out    dx, al
  778.     mov    al, ah
  779.     and    al, 0fh
  780.     inc    dx
  781.     out    dx, al
  782.     dec    dx
  783.     lodsb
  784.     mov    [byte es:di], al
  785.     add    di, PAGESIZE
  786.     mov    [byte es:di], al
  787.     sub    di, PAGESIZE
  788.     rol    ah, 1
  789.     adc    di, 0
  790.     dec    cx
  791.     jnz    @@xloop
  792.  
  793.     mov    di, BYTESPERLINE
  794.     add    di, [ofs]
  795.     dec    bl
  796.     jnz    @@yloop
  797.  
  798.     mov    ax, DGROUP
  799.     mov    ds, ax
  800.  
  801.     ret
  802.  
  803. endp    putspritedirect
  804.  
  805.  
  806. ; putsprite.
  807. ; Hence, as the name says, this routine displays the sprite 'handle'
  808. ; at coords 'x' and 'y'.
  809. ;
  810. ; NOTE: x coordinate will be truncated according to the 'align' member
  811. ;       of the 'lowspr' structure.
  812.  
  813. proc    putsprite uses si di,    handle:word, x:word, y:word, n:word
  814.  
  815. local    nx:word, ny:word, nxs:word, nys:word, cspace:word
  816.  
  817. ; First clipping will be performed.
  818.  
  819.     mov    si, [handle]
  820.     imul    si, size lowspr
  821.     add    si, offset _sprite
  822.  
  823.     mov    ax, [x]
  824.     and    ax, 0fffch        ; Truncate to a multiple of 4
  825.     cmp    ax, [windowx0]
  826.     jge    @@p1
  827.     mov    di, [windowx0]
  828.     neg    ax
  829.     add    ax, di
  830.     mov    dx, [(lowspr ptr si).xsalign]
  831.     cmp    ax, dx
  832.     jae    @@remove
  833.     sub    dx, ax
  834.     shr    ax, 2
  835.     mov    [cspace], ax
  836.     mov    bx, ax
  837.     mov    [nxs], dx
  838.     mov    [nx], di
  839.     jmp    @@ycheck
  840. @@p1:
  841.     mov    cx, ax
  842.     mov    dx, [(lowspr ptr si).xsalign]
  843.     add    cx, dx
  844.     cmp    cx, [windowx1]
  845.     jl    @@p2
  846.     mov    di, [windowx1]
  847.     cmp    ax, di
  848.     jge    @@remove
  849.     mov    [nx], ax
  850.     inc    di
  851.     sub    di, ax
  852.     mov    [nxs], di
  853.     sub    dx, di
  854.     shr    dx, 2
  855.     mov    [cspace], dx
  856.     xor    bx, bx
  857.     jmp    @@ycheck
  858. @@p2:
  859.     mov    [nx], ax
  860.     mov    [nxs], dx
  861.     mov    [cspace], 0
  862.     xor    bx, bx
  863.  
  864. @@ycheck:
  865.     mov     ax, [y]
  866.     cmp    ax, [windowy0]
  867.     jge    @@p3
  868.     mov    di, [windowy0]
  869.     neg    ax
  870.     add    ax, di
  871.     mov    dx, [(lowspr ptr si).ys]
  872.     cmp    ax, dx
  873.     jae    @@remove
  874.     sub    dx, ax
  875.     mov    [nys], dx
  876.     mov    cx, [(lowspr ptr si).xsalign]
  877.     shr    cx, 2
  878.     imul    cx
  879.     add    bx, ax
  880.     mov    [ny], di
  881.     jmp    @@donecheck
  882. @@p3:
  883.     mov    cx, ax
  884.     mov    dx, [(lowspr ptr si).ys]
  885.     add    cx, dx
  886.     cmp    cx, [windowy1]
  887.     jl    @@p4
  888.     mov    di, [windowy1]
  889.     cmp    ax, di
  890.     jge    @@remove
  891.     mov    [ny], ax
  892.     sub    di, ax
  893.     mov    [nys], di
  894.     jmp    @@donecheck
  895. @@p4:
  896.     mov    [ny], ax
  897.     mov    [nys], dx
  898.  
  899. @@donecheck:
  900.  
  901. ; Truncate clipped coordinated to a multiple of 4.
  902.     shr    [nx], 2
  903.     shr    [nxs], 2
  904.  
  905.     mov    di, [ny]
  906.     imul    di, BYTESPERLINE
  907.     add    di, [nx]            ; es:di -> screen memory
  908.     add    di, [page]
  909.  
  910.     mov    es, [base]
  911.  
  912.     mov    ax, [n]
  913.     mul     [word (lowspr ptr si).picsize]
  914.     mov    cx, [word (lowspr ptr si).data]
  915.     test    [x], 10b
  916.     jz    @@align4
  917.     add    ax, [(lowspr ptr si).seqsize]
  918. @@align4:
  919.     lds    si, [(lowspr ptr si).mask]    ;
  920.     add    bx, ax
  921.     add    si, bx                ; ds:si -> mask data.
  922.     add    bx, cx
  923.  
  924.     mov    dx, GC_INDEX
  925.     mov    ax, 0000h + BIT_MASK
  926.     out    dx, ax
  927.  
  928.     mov    dx, SC_INDEX
  929.     mov    ax, 0000h + MAP_MASK
  930.     out    dx, ax
  931.     inc    dx
  932.  
  933.     cld
  934.     mov    ch, [byte nys]
  935. @@next1:
  936.     mov    cl, [byte nxs]
  937.  
  938. @@next2:
  939.     lodsb
  940.     cmp    ah, al
  941.     je    @@skip
  942.     mov    ah, al
  943.     out    dx, al
  944. @@skip:
  945.     mov    al, [es:bx]
  946.     inc    bx
  947.     stosb
  948.  
  949.     dec    cl
  950.     jnz    @@next2
  951.  
  952.     add    di, BYTESPERLINE
  953.     sub    di, [nxs]
  954.     add    bx, [cspace]
  955.     add    si, [cspace]
  956.  
  957.     dec    ch
  958.     jnz    @@next1
  959.  
  960. @@remove:
  961.     mov    ax, DGROUP
  962.     mov    ds, ax
  963.  
  964.     ret
  965.  
  966. endp    putsprite
  967.  
  968.  
  969.     public    putflash
  970. proc    putflash uses si di,    handle:word, x:word, y:word, n:word
  971.  
  972. local    nx:word, ny:word, nxs:word, nys:word, cspace:word
  973.  
  974. ; First clipping will be performed.
  975.  
  976.     mov    si, [handle]
  977.     imul    si, size lowspr
  978.     add    si, offset _sprite
  979.  
  980.     mov    ax, [x]
  981.     and    ax, 0fffch        ; Truncate to a multiple of 4
  982.     cmp    ax, [windowx0]
  983.     jge    @@p1
  984.     mov    di, [windowx0]
  985.     neg    ax
  986.     add    ax, di
  987.     mov    dx, [(lowspr ptr si).xsalign]
  988.     cmp    ax, dx
  989.     jae    @@remove
  990.     sub    dx, ax
  991.     shr    ax, 2
  992.     mov    [cspace], ax
  993.     mov    bx, ax
  994.     mov    [nxs], dx
  995.     mov    [nx], di
  996.     jmp    @@ycheck
  997. @@p1:
  998.     mov    cx, ax
  999.     mov    dx, [(lowspr ptr si).xsalign]
  1000.     add    cx, dx
  1001.     cmp    cx, [windowx1]
  1002.     jl    @@p2
  1003.     mov    di, [windowx1]
  1004.     cmp    ax, di
  1005.     jge    @@remove
  1006.     mov    [nx], ax
  1007.     inc    di
  1008.     sub    di, ax
  1009.     mov    [nxs], di
  1010.     sub    dx, di
  1011.     shr    dx, 2
  1012.     mov    [cspace], dx
  1013.     xor    bx, bx
  1014.     jmp    @@ycheck
  1015. @@p2:
  1016.     mov    [nx], ax
  1017.     mov    [nxs], dx
  1018.     mov    [cspace], 0
  1019.     xor    bx, bx
  1020.  
  1021. @@ycheck:
  1022.     mov     ax, [y]
  1023.     cmp    ax, [windowy0]
  1024.     jge    @@p3
  1025.     mov    di, [windowy0]
  1026.     neg    ax
  1027.     add    ax, di
  1028.     mov    dx, [(lowspr ptr si).ys]
  1029.     cmp    ax, dx
  1030.     jae    @@remove
  1031.     sub    dx, ax
  1032.     mov    [nys], dx
  1033.     mov    cx, [(lowspr ptr si).xsalign]
  1034.     shr    cx, 2
  1035.     imul    cx
  1036.     add    bx, ax
  1037.     mov    [ny], di
  1038.     jmp    @@donecheck
  1039. @@p3:
  1040.     mov    cx, ax
  1041.     mov    dx, [(lowspr ptr si).ys]
  1042.     add    cx, dx
  1043.     cmp    cx, [windowy1]
  1044.     jl    @@p4
  1045.     mov    di, [windowy1]
  1046.     cmp    ax, di
  1047.     jge    @@remove
  1048.     mov    [ny], ax
  1049.     sub    di, ax
  1050.     mov    [nys], di
  1051.     jmp    @@donecheck
  1052. @@p4:
  1053.     mov    [ny], ax
  1054.     mov    [nys], dx
  1055.  
  1056. @@donecheck:
  1057.  
  1058.  
  1059. ; Truncate clipped coordinated to a multiple of 4.
  1060.     shr    [nx], 2
  1061.     shr    [nxs], 2
  1062.  
  1063.     mov    di, [ny]
  1064.     imul    di, BYTESPERLINE
  1065.     add    di, [nx]            ; es:di -> screen memory
  1066.     add    di, [page]
  1067.  
  1068.     mov    es, [base]
  1069.  
  1070.     mov    ax, [n]
  1071.     mul     [word (lowspr ptr si).picsize]
  1072.     mov    cx, [word (lowspr ptr si).data]
  1073.     test    [x], 10b
  1074.     jz    @@align4
  1075.     add    ax, [(lowspr ptr si).seqsize]
  1076. @@align4:
  1077.     mov    cl, [byte objflashcolor]    ; Preload flashcolor.
  1078.     lds    si, [(lowspr ptr si).mask]    ;
  1079.     add    bx, ax
  1080.     add    si, bx                ; ds:si -> mask data.
  1081.  
  1082.     mov    dx, GC_INDEX
  1083.     mov    ax, 0ff00h + BIT_MASK
  1084.     out    dx, ax
  1085.  
  1086.     mov    dx, SC_INDEX
  1087.     mov    ax, 0f00h + MAP_MASK
  1088.     out    dx, ax
  1089.     inc    dx
  1090.  
  1091.     cld
  1092.     mov    bh, [byte nys]
  1093. @@next1:
  1094.     mov    bl, [byte nxs]
  1095.  
  1096. @@next2:
  1097.     lodsb
  1098.     cmp    ah, al
  1099.     je    @@skip
  1100.     mov    ah, al
  1101.     out    dx, al
  1102. @@skip:
  1103.     mov    al, cl
  1104.     stosb
  1105.  
  1106.     dec    bl
  1107.     jnz    @@next2
  1108.  
  1109.     add    di, BYTESPERLINE
  1110.     sub    di, [nxs]
  1111.     add    si, [cspace]
  1112.  
  1113.     dec    bh
  1114.     jnz    @@next1
  1115.  
  1116. @@remove:
  1117.     mov    ax, DGROUP
  1118.     mov    ds, ax
  1119.  
  1120.     ret
  1121.  
  1122. endp    putflash
  1123.  
  1124.  
  1125. proc    removesprite uses si di,    handle:word, x:word, y:word
  1126.  
  1127. local    nx:word, ny:word, nxs:word, nys:word
  1128.  
  1129. ; First clipping will be performed.
  1130.  
  1131.     mov    si, [handle]
  1132.     imul    si, size lowspr
  1133.     add    si, offset _sprite
  1134.  
  1135.     mov    ax, [x]
  1136.     and    ax, 0fffch
  1137.     cmp    ax, [windowx0]
  1138.     jge    @@p1
  1139.     mov    di, [windowx0]
  1140.     neg    ax
  1141.     add    ax, di
  1142.     mov    dx, [(lowspr ptr si).xsalign]
  1143.     cmp    ax, dx
  1144.     jae    @@remove
  1145.     sub    dx, ax
  1146.     mov    [nxs], dx
  1147.     mov    [nx], di
  1148.     jmp    @@ycheck
  1149. @@p1:
  1150.     mov    cx, ax
  1151.     mov    dx, [(lowspr ptr si).xsalign]
  1152.     add    cx, dx
  1153.     cmp    cx, [windowx1]
  1154.     jl    @@p2
  1155.     mov    di, [windowx1]
  1156.     cmp    ax, di
  1157.     jge    @@remove
  1158.     mov    [nx], ax
  1159.     inc    di
  1160.     sub    di, ax
  1161.     mov    [nxs], di
  1162.     jmp    @@ycheck
  1163. @@p2:
  1164.     mov    [nx], ax
  1165.     mov    [nxs], dx
  1166.  
  1167. @@ycheck:
  1168.     mov     ax, [y]
  1169.     cmp    ax, [windowy0]
  1170.     jge    @@p3
  1171.     mov    di, [windowy0]
  1172.     neg    ax
  1173.     add    ax, di
  1174.     mov    dx, [(lowspr ptr si).ys]
  1175.     cmp    ax, dx
  1176.     jae    @@remove
  1177.     sub    dx, ax
  1178.     mov    [nys], dx
  1179.     mov    [ny], di
  1180.     jmp    @@donecheck
  1181. @@p3:
  1182.     mov    cx, ax
  1183.     mov    dx, [(lowspr ptr si).ys]
  1184.     add    cx, dx
  1185.     cmp    cx, [windowy1]
  1186.     jl    @@p4
  1187.     mov    di, [windowy1]
  1188.     cmp    ax, di
  1189.     jge    @@remove
  1190.     mov    [ny], ax
  1191.     sub    di, ax
  1192.     mov    [nys], di
  1193.     jmp    @@donecheck
  1194. @@p4:
  1195.     mov    [ny], ax
  1196.     mov    [nys], dx
  1197.  
  1198. @@donecheck:
  1199.  
  1200.  
  1201. ; Truncate clipped coordinated to a multiple of 4.
  1202.     shr    [nx], 2
  1203.     shr    [nxs], 2
  1204.  
  1205.     mov    es, [base]
  1206.  
  1207.     mov    di, [ny]
  1208.     imul    di, BYTESPERLINE
  1209.     add    di, [nx]            ; es:di -> screen memory
  1210.     add    di, [page]            ; Second Page.
  1211.  
  1212.     mov    dx, GC_INDEX
  1213.     mov    ax, 0ff00h + BIT_MASK
  1214.     out    dx, ax
  1215.     mov    dx, SC_INDEX
  1216.     mov    ax, 0f00h + MAP_MASK
  1217.     out    dx, ax
  1218.  
  1219.     mov    al, [byte backgrndcolor]
  1220.     cld
  1221.     mov    dx, [nys]
  1222. @@next1:
  1223.     mov    cx, [nxs]
  1224.  
  1225.     rep    stosb
  1226.  
  1227.     add    di, BYTESPERLINE
  1228.     sub    di, [nxs]
  1229.  
  1230.     dec    dx
  1231.     jnz    @@next1
  1232.  
  1233. @@remove:
  1234.     ret
  1235.  
  1236. endp    removesprite
  1237.  
  1238.  
  1239.  
  1240. ; updatescreen.
  1241. ; updatescreen removes the old objects from the backscreen and
  1242. ; redraws them at the latest positions.
  1243.  
  1244. proc    updatescreen uses bp si
  1245.  
  1246.     xor    [page], PAGESIZE
  1247.  
  1248.     call    starfield
  1249.  
  1250.     mov    si, offset _obj
  1251.     mov    bp, MAXOBJS
  1252. @@next1:
  1253.     cmp    [(objstrc ptr si).active], FALSE
  1254.     je    @@skip1
  1255.  
  1256. @@cycle:
  1257.     mov    ax, [(objstrc ptr si).n]
  1258.     add    ax, [(objstrc ptr si).nadd]
  1259.     cmp    ax, [(objstrc ptr si).maxn]
  1260.     jb    @@ok
  1261.     xor    ax, ax
  1262.     cmp    [(objstrc ptr si).cycle], 0
  1263.     je    @@ok
  1264.     mov    [(objstrc ptr si).destroy], 2
  1265.     mov    [(objstrc ptr si).cycle], 0
  1266. @@ok:
  1267.     mov    [(objstrc ptr si).n], ax
  1268.  
  1269.     call    removesprite, [(objstrc ptr si).sprite], [(objstrc ptr si).xb], [(objstrc ptr si).yb]
  1270.     cmp     [(objstrc ptr si).destroy], 0
  1271.     je    @@skip1
  1272.     dec    [(objstrc ptr si).destroy]
  1273.     jnz    @@skip1
  1274.     mov    [(objstrc ptr si).active], FALSE
  1275.  
  1276. @@skip1:
  1277.     add    si, size objstrc
  1278.     dec    bp
  1279.     jnz    @@next1
  1280.  
  1281.     mov    si, offset _obj
  1282.     mov    bp, MAXOBJS
  1283. @@next2:
  1284.     cmp    [(objstrc ptr si).active], FALSE
  1285.     je    @@skip2
  1286.  
  1287.     mov    ax, [(objstrc ptr si).xa]
  1288.     mov    [(objstrc ptr si).xb], ax
  1289.     mov    ax, [(objstrc ptr si).ya]
  1290.     mov    [(objstrc ptr si).yb], ax
  1291.     mov    ax, [(objstrc ptr si).x]
  1292.     mov    [(objstrc ptr si).xa], ax
  1293.     mov    ax, [(objstrc ptr si).y]
  1294.     mov    [(objstrc ptr si).ya], ax
  1295.  
  1296.     cmp    [(objstrc ptr si).destroy], 0
  1297.     jne    @@skip2
  1298.  
  1299. ; Draw new object.
  1300.     mov    ax, [(objstrc ptr si).n]
  1301.     shr    ax, 1
  1302.     test    [(objstrc ptr si).flags], O_FLASH
  1303.     jnz    @@flash
  1304.     call    putsprite, [(objstrc ptr si).sprite], [(objstrc ptr si).x], [(objstrc ptr si).y], ax
  1305.     jmp    @@skip2
  1306. @@flash:
  1307.     call    putflash, [(objstrc ptr si).sprite], [(objstrc ptr si).x], [(objstrc ptr si).y], ax
  1308.     and    [(objstrc ptr si).flags], not O_FLASH
  1309.  
  1310. @@skip2:
  1311.     add    si, size objstrc
  1312.     dec    bp
  1313.     jnz    @@next2
  1314.  
  1315.     call    showofs, [page]
  1316.  
  1317.     ret
  1318.  
  1319. endp    updatescreen
  1320.  
  1321.  
  1322.  
  1323. ; copypage: Copies a screen page to another.
  1324. ;        scr: source page (0, or 1)
  1325. ;           dst: destination page (0 or 1)
  1326.  
  1327. proc    copypage uses si di ds,    scr:word, dst:word
  1328.  
  1329.     mov    si, [scr]
  1330.     imul    si, PAGESIZE
  1331.     mov    di, [dst]
  1332.     imul    di, PAGESIZE
  1333.  
  1334.     mov    dx, GC_INDEX
  1335.     mov    ax, 0000h + BIT_MASK
  1336.     out    dx, ax
  1337.  
  1338.     mov    dx, SC_INDEX
  1339.     mov    ax, 0f00h + MAP_MASK
  1340.     out    dx, ax
  1341.     inc    dx
  1342.  
  1343.     mov    ax, [base]
  1344.     mov    es, ax
  1345.     mov    ds, ax
  1346.  
  1347.     mov    cx, PAGESIZE
  1348.     cld
  1349.     rep    movsb
  1350.  
  1351.     ret
  1352.  
  1353. endp    copypage
  1354.  
  1355.  
  1356. ; Slowly fades out the screen.
  1357. proc    glowout    uses si
  1358.  
  1359.     cld
  1360.     sub    bx, bx
  1361. @@m1:
  1362.     mov    si, offset palette
  1363. @@m2:
  1364.  
  1365. ; Wait for vertical retrace.
  1366.     mov    dx, INPUT_STATUS
  1367. @@wait:
  1368.     in    al, dx
  1369.     test    al, 08h
  1370.     jz    @@wait
  1371.  
  1372. ; Select starting color.
  1373.     mov    dx, 3c8h
  1374.     mov    al, bl
  1375.     out    dx, al
  1376.  
  1377. ; Start moving color datas.
  1378.     inc    dx
  1379.     mov    cx, 80h
  1380. @@loop:
  1381.     lodsb                           ; Fetch original red value and ...
  1382.     sub    al, bh                  ; ...calculate new color value by
  1383.                     ;   simply subtract the loop counter.
  1384.     jnc    @@r
  1385.     sub    al, al
  1386. @@r:
  1387.     out    dx, al            ; And out to the controller.
  1388.     lodsb                    ; Fetch green.
  1389.     sub    al, bh
  1390.     jnc    @@g
  1391.     sub    al, al
  1392. @@g:
  1393.     out    dx, al
  1394.     lodsb                ; And blue.
  1395.     sub    al, bh
  1396.     jnc    @@b
  1397.     sub    al, al
  1398. @@b:
  1399.     out    dx, al
  1400.  
  1401.     loop    @@loop
  1402.  
  1403.     add    bl, 80h
  1404.     jnz    @@m2
  1405.  
  1406.     add    bh, 6
  1407.     cmp    bh, 3fh
  1408.     jbe    @@m1
  1409.  
  1410.     ret
  1411.  
  1412. endp    glowout
  1413.  
  1414.  
  1415. proc    glowin    uses si,    dir:word
  1416.  
  1417.     cld
  1418.     mov    bx, 3c00h
  1419. @@m1:
  1420.     mov    si, offset palette
  1421. @@m2:
  1422.  
  1423. ; Wait for vertical retrace.
  1424.     mov    dx, INPUT_STATUS
  1425. @@wait:
  1426.     in    al, dx
  1427.     test    al, 08h
  1428.     jz    @@wait
  1429.  
  1430. ; Select starting color.
  1431.     mov    dx, 3c8h
  1432.     mov    al, bl
  1433.     out    dx, al
  1434.  
  1435. ; Start moving color datas.
  1436.     inc    dx
  1437.     mov    cx, 80h
  1438. @@loop:
  1439.     lodsb                           ; Fetch original red value and ...
  1440.     sub    al, bh                  ; ...calculate new color value by
  1441.                     ;   simply subtract the loop counter.
  1442.     jnc    @@r
  1443.     sub    al, al
  1444. @@r:
  1445.     out    dx, al            ; And out to the controller.
  1446.     lodsb                    ; Fetch green.
  1447.     sub    al, bh
  1448.     jnc    @@g
  1449.     sub    al, al
  1450. @@g:
  1451.     out    dx, al
  1452.     lodsb                ; And blue.
  1453.     sub    al, bh
  1454.     jnc    @@b
  1455.     sub    al, al
  1456. @@b:
  1457.     out    dx, al
  1458.  
  1459.     loop    @@loop
  1460.  
  1461.     add    bl, 80h
  1462.     jnz    @@m2
  1463.  
  1464.     sub    bh, 6
  1465.     jnc    @@m1
  1466.  
  1467.  
  1468.     ret
  1469.  
  1470. endp    glowin
  1471.  
  1472.  
  1473.     end
  1474.  
  1475.  
  1476.